package models

import (
	"encoding/json"
	"fmt"
	"strconv"
	"time"

	"gorm.io/gorm"
)

type Article struct {
	Id           int       `json:"id" gorm:"primaryKey"`
	ChannelId    int       `json:"channel_id"`
	Content      string    `json:"content"`
	Title        string    `json:"title"`
	Type         int       `json:"type"`
	Cover        Cover     `json:"cover" gorm:"-"`     // 忽略数据库映射
	CoverRaw     string    `gorm:"type:json" json:"-"` // 存储 JSON 的原始数据
	LikeCount    int       `json:"like_count"`
	Pubdate      time.Time `json:"-"`
	PubdateStr   string    `json:"pubdate" gorm:"-"`
	ReadCount    int       `json:"read_count"`
	CommentCount int       `json:"comment_count"`
	Status       int       `json:"status"`
}

type Cover struct {
	Type   int      `json:"type"`
	Images []string `json:"images"`
}

// 保存前：将 Cover 序列化为 JSON 存入 CoverRaw。钩子函数会自动执行，无需调用
func (a *Article) BeforeSave(*gorm.DB) error {
	a.Pubdate = time.Now()
	coverBytes, err := json.Marshal(a.Cover)
	if err != nil {
		return err
	}
	a.CoverRaw = string(coverBytes)
	return nil
}

// 查询后：将 CoverRaw 解析到 Cover 字段。钩子函数会自动执行，无需调用
func (a *Article) AfterFind(*gorm.DB) error {
	a.PubdateStr = a.Pubdate.Format("2006-01-02 15:04:05")
	if a.CoverRaw != "" {
		return json.Unmarshal([]byte(a.CoverRaw), &a.Cover)
	}
	return nil
}

// 存储单条数据
func (a Article) CreateArticle(article *Article) error {
	result := DB.Create(article)
	if result.Error != nil {
		return fmt.Errorf("插入失败: %w", result.Error)
	}
	fmt.Printf("插入成功, ID: %d, 影响行数: %d\n", article.Id, result.RowsAffected)

	var fn = func(id int, status int) {
		time.Sleep(time.Minute * 2)
		Article{}.UpdateArticleStatus(article.Id, 2)
	}
	go fn(article.Id, 2)
	return nil
}

// 更新数据
func (a Article) UpdateArticleStatus(id int, status int) error {
	var article Article
	result := DB.Model(&Article{}).Where("id = ?", id).Update("status", status)
	if result.Error != nil {
		return fmt.Errorf("更新失败: %w", result.Error)
	}
	fmt.Printf("更新成功, ID: %d, 影响行数: %d\n", article.Id, result.RowsAffected)
	return nil
}

// 查询所有数据
func (a Article) GetAllArticles() ([]Article, error) {
	var articles []Article
	result := DB.Find(&articles)
	if result.Error != nil {
		return nil, fmt.Errorf("查询失败: %w", result.Error)
	}
	fmt.Printf("查询到 %d 条记录\n", result.RowsAffected)
	return articles, nil
}

// 根据id删除一条数据
func (a Article) DeletelArticleById(id int) (Article, error) {
	var articles Article
	result := DB.Where("id = ?", id).Delete(&articles)
	if result.Error != nil {
		return articles, fmt.Errorf("删除失败: %w", result.Error)
	}
	fmt.Printf("删除了 %d 条记录\n", result.RowsAffected)
	return articles, nil
}

// 根据id查询一条数据
func (a Article) QueryArticleById(id int) (Article, error) {
	var articles Article
	result := DB.Where("id = ?", id).Find(&articles)
	if result.Error != nil {
		return articles, fmt.Errorf("查询失败: %w", result.Error)
	}
	fmt.Printf("查询了 %d 条记录\n", result.RowsAffected)
	return articles, nil
}

// 修改一条数据
func (a *Article) UpdateArticle() error {
	result := DB.Save(a)
	if result.Error != nil {
		return fmt.Errorf("修改失败: %w", result.Error)
	}
	fmt.Printf("修改了 %d 条记录\n", result.RowsAffected)
	return nil
}

// 根据条件动态查询数据
func (a Article) QueryArticlesByConditions(conditions map[string]string) ([]Article, error) {
	var articles []Article
	fmt.Println("conditions:", conditions)
	DB := DB.Model(&Article{})

	if v, ok := conditions["id"]; ok {
		if id, err := strconv.Atoi(v); err == nil {
			DB = DB.Where("id = ?", id)
		}
	}

	if v, ok := conditions["status"]; ok {
		if status, err := strconv.Atoi(v); err == nil {
			DB = DB.Where("status = ?", status)
		}
	}

	if v, ok := conditions["channel_id"]; ok {
		if channel_id, err := strconv.Atoi(v); err == nil {
			DB = DB.Where("channel_id = ?", channel_id)
		}
	}

	if v, ok := conditions["begin_pubdate"]; ok {
		DB = DB.Where("pubdate >=  ?", v)
	}

	if v, ok := conditions["end_pubdate"]; ok {
		DB = DB.Where("pubdate <=  ?", v)
	}

	result := DB.Order("pubdate").Find(&articles)
	if result.Error != nil {
		return articles, fmt.Errorf("查询失败: %w", result.Error)
	}
	fmt.Printf("查询了 %d 条记录\n", result.RowsAffected)
	return articles, nil
}

// 获取频道对应文章count件数
func (a Article) QueryArticlesCount(channels map[string]int) (map[string]int, int) {
	var count int64
	channelCount := make(map[string]int)
	for k, v := range channels {
		DB.Table("articles").Where("channel_id =  ?", v).Count(&count)
		channelCount[k] = int(count)
	}
	DB.Table("articles").Count(&count)
	return channelCount, int(count)
}
